package com.acme;

import java.util.List;

import com.acme.bankapp.domain.account.CheckingAccount;
import com.acme.bankapp.domain.account.SavingAccount;
import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.ClientRegistrationListener;
import com.acme.bankapp.domain.client.Client;
import com.acme.bankapp.domain.client.Gender;
import com.acme.bankapp.exceptions.ClientExistsException;
import com.acme.bankapp.exceptions.NotEnoughFundsException;
import com.acme.bankapp.exceptions.OverDraftLimitExceededException;
import com.acme.bankapp.service.bank.BankService;

/**
 * Class used to manage bank, clients and accounts. Can print some useful
 * information.
 *
 * @author S.Zhidkov
 */
public class BankApplication {

    private static final String MESSAGE_BANK_CLIENTS = "Bank clients:";
    private static final int LISTENER_NUMBER = 3;

    private Bank bank;
    private BankService bankService;

    public BankApplication() {

        ClientRegistrationListener[] listeners = new ClientRegistrationListener[LISTENER_NUMBER];
        listeners[0] = new Bank.PrintClientListener();
        listeners[1] = new Bank.EmailNotificationListener();
        listeners[2] = new Bank.DebugListener();

        bank = new Bank(listeners);

        bankService = new BankService();

        Client client1 = new Client("Anna", 21, Gender.FEMALE);
        Client client2 = new Client("Bob", 55, Gender.MALE);
        Client client3 = new Client("Lane", 31, Gender.FEMALE);

        client1.addAccount(new SavingAccount(1, 300));
        client2.addAccount(new CheckingAccount(2, 1000, 200));
        client3.addAccount(new SavingAccount(3, 800));

        try {
            bankService.addClient(bank, client1);
            bankService.addClient(bank, client2);
            bankService.addClient(bank, client3);
        } catch (ClientExistsException e) {
            e.printStackTrace();
        }
    }

    private void modifyBank() {
        List<Client> clients = bank.getClients();

        // change client 1
        clients.get(0).getAccounts().deposit(1000);
        try {
            clients.get(0).getAccounts().withdraw(1200);
        } catch (NotEnoughFundsException e) {
            e.printStackTrace();
        }

        // change client 2
        clients.get(1).getAccounts().deposit(150);
        try {
            clients.get(1).getAccounts().withdraw(3000);
        } catch (OverDraftLimitExceededException e) {
            e.printStackTrace();
            System.out.println(e.getAccount().maximumAmountToWithdraw());
        } catch (NotEnoughFundsException e) {
            e.printStackTrace();
        }

        bankService.printMaximumAmountToWithdraw(bank);
    }

    /**
     * Prints balance of the all clients.
     */
    public void printBalance() {
        List<Client> clients = bank.getClients();

        System.out.println(MESSAGE_BANK_CLIENTS);
        for (Client client : clients) {
            System.out.println(client);
        }
    }

    public static void main(String[] args) {
        BankApplication bankApp = new BankApplication();
        bankApp.printBalance();
        bankApp.modifyBank();
        bankApp.printBalance();
    }

}
